home *** CD-ROM | disk | FTP | other *** search
/ Aminet 32 / Aminet 32 (1999)(Schatztruhe)[!][Aug 1999].iso / Aminet / dev / lang / Python151_Src.lha / Python1.5_Source / Objects / fileobject.c < prev    next >
C/C++ Source or Header  |  1998-05-30  |  21KB  |  1,042 lines

  1. /***********************************************************
  2. Copyright 1991-1995 by Stichting Mathematisch Centrum, Amsterdam,
  3. The Netherlands.
  4.  
  5.                         All Rights Reserved
  6.  
  7. Permission to use, copy, modify, and distribute this software and its
  8. documentation for any purpose and without fee is hereby granted,
  9. provided that the above copyright notice appear in all copies and that
  10. both that copyright notice and this permission notice appear in
  11. supporting documentation, and that the names of Stichting Mathematisch
  12. Centrum or CWI or Corporation for National Research Initiatives or
  13. CNRI not be used in advertising or publicity pertaining to
  14. distribution of the software without specific, written prior
  15. permission.
  16.  
  17. While CWI is the initial source for this software, a modified version
  18. is made available by the Corporation for National Research Initiatives
  19. (CNRI) at the Internet address ftp://ftp.python.org.
  20.  
  21. STICHTING MATHEMATISCH CENTRUM AND CNRI DISCLAIM ALL WARRANTIES WITH
  22. REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
  23. MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH
  24. CENTRUM OR CNRI BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
  25. DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
  26. PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
  27. TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
  28. PERFORMANCE OF THIS SOFTWARE.
  29.  
  30. ******************************************************************/
  31.  
  32. /* File object implementation */
  33.  
  34. #include "Python.h"
  35. #include "structmember.h"
  36.  
  37. #ifdef HAVE_UNISTD_H
  38. #include <unistd.h>
  39. #endif
  40.  
  41. #ifdef MS_WIN32
  42. #define ftruncate _chsize
  43. #define fileno _fileno
  44. #define HAVE_FTRUNCATE
  45. #endif
  46.  
  47. #ifdef THINK_C
  48. #define HAVE_FOPENRF
  49. #endif
  50. #ifdef __MWERKS__
  51. /* Mwerks fopen() doesn't always set errno */
  52. #define NO_FOPEN_ERRNO
  53. #endif
  54.  
  55. #define BUF(v) PyString_AS_STRING((PyStringObject *)v)
  56.  
  57. #include <errno.h>
  58.  
  59. typedef struct {
  60.     PyObject_HEAD
  61.     FILE *f_fp;
  62.     PyObject *f_name;
  63.     PyObject *f_mode;
  64.     int (*f_close) Py_PROTO((FILE *));
  65.     int f_softspace; /* Flag used by 'print' command */
  66. } PyFileObject;
  67.  
  68. #include "protos/fileobject_protos.h"
  69.  
  70. FILE *
  71. PyFile_AsFile(f)
  72.     PyObject *f;
  73. {
  74.     if (f == NULL || !PyFile_Check(f))
  75.         return NULL;
  76.     else
  77.         return ((PyFileObject *)f)->f_fp;
  78. }
  79.  
  80. PyObject *
  81. PyFile_Name(f)
  82.     PyObject *f;
  83. {
  84.     if (f == NULL || !PyFile_Check(f))
  85.         return NULL;
  86.     else
  87.         return ((PyFileObject *)f)->f_name;
  88. }
  89.  
  90. PyObject *
  91. PyFile_FromFile(fp, name, mode, close)
  92.     FILE *fp;
  93.     char *name;
  94.     char *mode;
  95.     int (*close) Py_FPROTO((FILE *));
  96. {
  97.     PyFileObject *f = PyObject_NEW(PyFileObject, &PyFile_Type);
  98.     if (f == NULL)
  99.         return NULL;
  100.     f->f_fp = NULL;
  101.     f->f_name = PyString_FromString(name);
  102.     f->f_mode = PyString_FromString(mode);
  103.     f->f_close = close;
  104.     f->f_softspace = 0;
  105.     if (f->f_name == NULL || f->f_mode == NULL) {
  106.         Py_DECREF(f);
  107.         return NULL;
  108.     }
  109.     f->f_fp = fp;
  110.     return (PyObject *) f;
  111. }
  112.  
  113. PyObject *
  114. PyFile_FromString(name, mode)
  115.     char *name, *mode;
  116. {
  117.     extern int fclose Py_PROTO((FILE *));
  118.     PyFileObject *f;
  119.     f = (PyFileObject *) PyFile_FromFile((FILE *)NULL, name, mode, fclose);
  120.     if (f == NULL)
  121.         return NULL;
  122. #ifdef HAVE_FOPENRF
  123.     if (*mode == '*') {
  124.         FILE *fopenRF();
  125.         f->f_fp = fopenRF(name, mode+1);
  126.     }
  127.     else
  128. #endif
  129.     {
  130.         Py_BEGIN_ALLOW_THREADS
  131.         f->f_fp = fopen(name, mode);
  132.         Py_END_ALLOW_THREADS
  133.     }
  134.     if (f->f_fp == NULL) {
  135. #ifdef NO_FOPEN_ERRNO
  136.         if ( errno == 0 ) {
  137.             PyErr_SetString(PyExc_IOError, "Cannot open file");
  138.             Py_DECREF(f);
  139.             return NULL;
  140.         }
  141. #endif
  142.         PyErr_SetFromErrno(PyExc_IOError);
  143.         Py_DECREF(f);
  144.         return NULL;
  145.     }
  146.     return (PyObject *)f;
  147. }
  148.  
  149. void
  150. PyFile_SetBufSize(f, bufsize)
  151.     PyObject *f;
  152.     int bufsize;
  153. {
  154.     if (bufsize >= 0) {
  155. #ifdef HAVE_SETVBUF
  156.         int type;
  157.         switch (bufsize) {
  158.         case 0:
  159.             type = _IONBF;
  160.             break;
  161.         case 1:
  162.             type = _IOLBF;
  163.             bufsize = BUFSIZ;
  164.             break;
  165.         default:
  166.             type = _IOFBF;
  167.         }
  168.         setvbuf(((PyFileObject *)f)->f_fp, (char *)NULL,
  169.             type, bufsize);
  170. #else /* !HAVE_SETVBUF */
  171.         if (bufsize <= 1)
  172.             setbuf(((PyFileObject *)f)->f_fp, (char *)NULL);
  173. #endif /* !HAVE_SETVBUF */
  174.     }
  175. }
  176.  
  177. static PyObject *
  178. err_closed()
  179. {
  180.     PyErr_SetString(PyExc_ValueError, "I/O operation on closed file");
  181.     return NULL;
  182. }
  183.  
  184. /* Methods */
  185.  
  186. static void
  187. file_dealloc(f)
  188.     PyFileObject *f;
  189. {
  190.     if (f->f_fp != NULL && f->f_close != NULL) {
  191.         Py_BEGIN_ALLOW_THREADS
  192.         (*f->f_close)(f->f_fp);
  193.         Py_END_ALLOW_THREADS
  194.     }
  195.     if (f->f_name != NULL) {
  196.         Py_DECREF(f->f_name);
  197.     }
  198.     if (f->f_mode != NULL) {
  199.         Py_DECREF(f->f_mode);
  200.     }
  201.     free((char *)f);
  202. }
  203.  
  204. static PyObject *
  205. file_repr(f)
  206.     PyFileObject *f;
  207. {
  208.     char buf[300];
  209.     sprintf(buf, "<%s file '%.256s', mode '%.10s' at %lx>",
  210.         f->f_fp == NULL ? "closed" : "open",
  211.         PyString_AsString(f->f_name),
  212.         PyString_AsString(f->f_mode),
  213.         (long)f);
  214.     return PyString_FromString(buf);
  215. }
  216.  
  217. static PyObject *
  218. file_close(f, args)
  219.     PyFileObject *f;
  220.     PyObject *args;
  221. {
  222.     int sts = 0;
  223.     if (!PyArg_NoArgs(args))
  224.         return NULL;
  225.     if (f->f_fp != NULL) {
  226.         if (f->f_close != NULL) {
  227.             Py_BEGIN_ALLOW_THREADS
  228.             errno = 0;
  229.             sts = (*f->f_close)(f->f_fp);
  230.             Py_END_ALLOW_THREADS
  231.         }
  232.         f->f_fp = NULL;
  233.     }
  234.     if (sts == EOF)
  235.         return PyErr_SetFromErrno(PyExc_IOError);
  236.     if (sts != 0)
  237.         return PyInt_FromLong((long)sts);
  238.     Py_INCREF(Py_None);
  239.     return Py_None;
  240. }
  241.  
  242. static PyObject *
  243. file_seek(f, args)
  244.     PyFileObject *f;
  245.     PyObject *args;
  246. {
  247.     long offset;
  248.     int whence;
  249.     int ret;
  250.     
  251.     if (f->f_fp == NULL)
  252.         return err_closed();
  253.     whence = 0;
  254.     if (!PyArg_Parse(args, "l", &offset)) {
  255.         PyErr_Clear();
  256.         if (!PyArg_Parse(args, "(li)", &offset, &whence))
  257.             return NULL;
  258.     }
  259.     Py_BEGIN_ALLOW_THREADS
  260.     errno = 0;
  261.     ret = fseek(f->f_fp, offset, whence);
  262.     Py_END_ALLOW_THREADS
  263.     if (ret != 0) {
  264.         PyErr_SetFromErrno(PyExc_IOError);
  265.         clearerr(f->f_fp);
  266.         return NULL;
  267.     }
  268.     Py_INCREF(Py_None);
  269.     return Py_None;
  270. }
  271.  
  272. #ifdef HAVE_FTRUNCATE
  273. static PyObject *
  274. file_truncate(f, args)
  275.     PyFileObject *f;
  276.     PyObject *args;
  277. {
  278.     long newsize;
  279.     int ret;
  280.     
  281.     if (f->f_fp == NULL)
  282.         return err_closed();
  283.     if (!PyArg_Parse(args, "l", &newsize)) {
  284.         PyErr_Clear();
  285.         if (!PyArg_NoArgs(args))
  286.                 return NULL;
  287.         Py_BEGIN_ALLOW_THREADS
  288.         errno = 0;
  289.         newsize =  ftell(f->f_fp); /* default to current position*/
  290.         Py_END_ALLOW_THREADS
  291.         if (newsize == -1L) {
  292.                 PyErr_SetFromErrno(PyExc_IOError);
  293.             clearerr(f->f_fp);
  294.             return NULL;
  295.         }
  296.     }
  297.     Py_BEGIN_ALLOW_THREADS
  298.     errno = 0;
  299.     ret = fflush(f->f_fp);
  300.     Py_END_ALLOW_THREADS
  301.     if (ret == 0) {
  302.             Py_BEGIN_ALLOW_THREADS
  303.         errno = 0;
  304.         ret = ftruncate(fileno(f->f_fp), newsize);
  305.         Py_END_ALLOW_THREADS
  306.     }
  307.     if (ret != 0) {
  308.         PyErr_SetFromErrno(PyExc_IOError);
  309.         clearerr(f->f_fp);
  310.         return NULL;
  311.     }
  312.     Py_INCREF(Py_None);
  313.     return Py_None;
  314. }
  315. #endif /* HAVE_FTRUNCATE */
  316.  
  317. static PyObject *
  318. file_tell(f, args)
  319.     PyFileObject *f;
  320.     PyObject *args;
  321. {
  322.     long offset;
  323.     if (f->f_fp == NULL)
  324.         return err_closed();
  325.     if (!PyArg_NoArgs(args))
  326.         return NULL;
  327.     Py_BEGIN_ALLOW_THREADS
  328.     errno = 0;
  329.     offset = ftell(f->f_fp);
  330.     Py_END_ALLOW_THREADS
  331.     if (offset == -1L) {
  332.         PyErr_SetFromErrno(PyExc_IOError);
  333.         clearerr(f->f_fp);
  334.         return NULL;
  335.     }
  336.     return PyInt_FromLong(offset);
  337. }
  338.  
  339. static PyObject *
  340. file_fileno(f, args)
  341.     PyFileObject *f;
  342.     PyObject *args;
  343. {
  344.     if (f->f_fp == NULL)
  345.         return err_closed();
  346.     if (!PyArg_NoArgs(args))
  347.         return NULL;
  348.     return PyInt_FromLong((long) fileno(f->f_fp));
  349. }
  350.  
  351. static PyObject *
  352. file_flush(f, args)
  353.     PyFileObject *f;
  354.     PyObject *args;
  355. {
  356.     int res;
  357.     
  358.     if (f->f_fp == NULL)
  359.         return err_closed();
  360.     if (!PyArg_NoArgs(args))
  361.         return NULL;
  362.     Py_BEGIN_ALLOW_THREADS
  363.     errno = 0;
  364.     res = fflush(f->f_fp);
  365.     Py_END_ALLOW_THREADS
  366.     if (res != 0) {
  367.         PyErr_SetFromErrno(PyExc_IOError);
  368.         clearerr(f->f_fp);
  369.         return NULL;
  370.     }
  371.     Py_INCREF(Py_None);
  372.     return Py_None;
  373. }
  374.  
  375. static PyObject *
  376. file_isatty(f, args)
  377.     PyFileObject *f;
  378.     PyObject *args;
  379. {
  380.     long res;
  381.     if (f->f_fp == NULL)
  382.         return err_closed();
  383.     if (!PyArg_NoArgs(args))
  384.         return NULL;
  385.     Py_BEGIN_ALLOW_THREADS
  386.     res = isatty((int)fileno(f->f_fp));
  387.     Py_END_ALLOW_THREADS
  388.     return PyInt_FromLong(res);
  389. }
  390.  
  391. /* We expect that fstat exists on most systems.
  392.    It's confirmed on Unix, Mac and Windows.
  393.    If you don't have it, add #define DONT_HAVE_FSTAT to your config.h. */
  394. #ifndef DONT_HAVE_FSTAT
  395. #define HAVE_FSTAT
  396.  
  397. #include <sys/types.h>
  398. #include <sys/stat.h>
  399.  
  400. #endif
  401.  
  402. #if BUFSIZ < 8192
  403. #define SMALLCHUNK 8192
  404. #else
  405. #define SMALLCHUNK BUFSIZ
  406. #endif
  407.  
  408. #define BIGCHUNK (512*1024)
  409.  
  410. static size_t
  411. new_buffersize(f, currentsize)
  412.     PyFileObject *f;
  413.     size_t currentsize;
  414. {
  415. #ifdef HAVE_FSTAT
  416.     long pos, end;
  417.     struct stat st;
  418.     if (fstat(fileno(f->f_fp), &st) == 0) {
  419.         end = st.st_size;
  420.         pos = ftell(f->f_fp);
  421.         if (end > pos && pos >= 0)
  422.             return end - pos + 1;
  423.         /* Add 1 so if the file were to grow we'd notice. */
  424.     }
  425. #endif
  426.     if (currentsize > SMALLCHUNK) {
  427.         /* Keep doubling until we reach BIGCHUNK;
  428.            then keep adding BIGCHUNK. */
  429.         if (currentsize <= BIGCHUNK)
  430.             return currentsize + currentsize;
  431.         else
  432.             return currentsize + BIGCHUNK;
  433.     }
  434.     return currentsize + SMALLCHUNK;
  435. }
  436.  
  437. static PyObject *
  438. file_read(f, args)
  439.     PyFileObject *f;
  440.     PyObject *args;
  441. {
  442.     long bytesrequested = -1;
  443.     size_t bytesread, buffersize, chunksize;
  444.     PyObject *v;
  445.     
  446.     if (f->f_fp == NULL)
  447.         return err_closed();
  448.     if (!PyArg_ParseTuple(args, "|l", &bytesrequested))
  449.         return NULL;
  450.     if (bytesrequested < 0)
  451.         buffersize = new_buffersize(f, 0);
  452.     else
  453.         buffersize = bytesrequested;
  454.     v = PyString_FromStringAndSize((char *)NULL, buffersize);
  455.     if (v == NULL)
  456.         return NULL;
  457.     bytesread = 0;
  458.     for (;;) {
  459.         Py_BEGIN_ALLOW_THREADS
  460.         errno = 0;
  461.         chunksize = fread(BUF(v) + bytesread, 1,
  462.                   buffersize - bytesread, f->f_fp);
  463.         Py_END_ALLOW_THREADS
  464.         if (chunksize == 0) {
  465.             if (!ferror(f->f_fp))
  466.                 break;
  467.             PyErr_SetFromErrno(PyExc_IOError);
  468.             clearerr(f->f_fp);
  469.             Py_DECREF(v);
  470.             return NULL;
  471.         }
  472.         bytesread += chunksize;
  473.         if (bytesread < buffersize)
  474.             break;
  475.         if (bytesrequested < 0) {
  476.             buffersize = bytesread + new_buffersize(f, buffersize);
  477.             if (_PyString_Resize(&v, buffersize) < 0)
  478.                 return NULL;
  479.         }
  480.     }
  481.     if (bytesread != buffersize)
  482.         _PyString_Resize(&v, bytesread);
  483.     return v;
  484. }
  485.  
  486. static PyObject *
  487. file_readinto(f, args)
  488.     PyFileObject *f;
  489.     PyObject *args;
  490. {
  491.     char *ptr;
  492.     int ntodo, ndone, nnow;
  493.     
  494.     if (f->f_fp == NULL)
  495.         return err_closed();
  496.     if (!PyArg_Parse(args, "w#", &ptr, &ntodo))
  497.         return NULL;
  498.     ndone = 0;
  499.     while (ntodo > 0) {
  500.         Py_BEGIN_ALLOW_THREADS
  501.         errno = 0;
  502.         nnow = fread(ptr+ndone, 1, ntodo, f->f_fp);
  503.         Py_END_ALLOW_THREADS
  504.         if (nnow == 0) {
  505.             if (!ferror(f->f_fp))
  506.                 break;
  507.             PyErr_SetFromErrno(PyExc_IOError);
  508.             clearerr(f->f_fp);
  509.             return NULL;
  510.         }
  511.         ndone += nnow;
  512.         ntodo -= nnow;
  513.     }
  514.     return PyInt_FromLong(ndone);
  515. }
  516.  
  517.  
  518. /* Internal routine to get a line.
  519.    Size argument interpretation:
  520.    > 0: max length;
  521.    = 0: read arbitrary line;
  522.    < 0: strip trailing '\n', raise EOFError if EOF reached immediately
  523. */
  524.  
  525. static PyObject *
  526. getline(f, n)
  527.     PyFileObject *f;
  528.     int n;
  529. {
  530.     register FILE *fp;
  531.     register int c;
  532.     register char *buf, *end;
  533.     int n1, n2;
  534.     PyObject *v;
  535.  
  536.     fp = f->f_fp;
  537.     n2 = n > 0 ? n : 100;
  538.     v = PyString_FromStringAndSize((char *)NULL, n2);
  539.     if (v == NULL)
  540.         return NULL;
  541.     buf = BUF(v);
  542.     end = buf + n2;
  543.  
  544.     Py_BEGIN_ALLOW_THREADS
  545.     for (;;) {
  546.         if ((c = getc(fp)) == EOF) {
  547.             clearerr(fp);
  548.             Py_BLOCK_THREADS
  549.             if (PyErr_CheckSignals()) {
  550.                 Py_DECREF(v);
  551.                 return NULL;
  552.             }
  553.             if (n < 0 && buf == BUF(v)) {
  554.                 Py_DECREF(v);
  555.                 PyErr_SetString(PyExc_EOFError,
  556.                        "EOF when reading a line");
  557.                 return NULL;
  558.             }
  559.             Py_UNBLOCK_THREADS
  560.             break;
  561.         }
  562.         if ((*buf++ = c) == '\n') {
  563.             if (n < 0)
  564.                 buf--;
  565.             break;
  566.         }
  567.         if (buf == end) {
  568.             if (n > 0)
  569.                 break;
  570.             n1 = n2;
  571.             n2 += 1000;
  572.             Py_BLOCK_THREADS
  573.             if (_PyString_Resize(&v, n2) < 0)
  574.                 return NULL;
  575.             Py_UNBLOCK_THREADS
  576.             buf = BUF(v) + n1;
  577.             end = BUF(v) + n2;
  578.         }
  579.     }
  580.     Py_END_ALLOW_THREADS
  581.  
  582.     n1 = buf - BUF(v);
  583.     if (n1 != n2)
  584.         _PyString_Resize(&v, n1);
  585.     return v;
  586. }
  587.  
  588. /* External C interface */
  589.  
  590. PyObject *
  591. PyFile_GetLine(f, n)
  592.     PyObject *f;
  593.     int n;
  594. {
  595.     if (f == NULL) {
  596.         PyErr_BadInternalCall();
  597.         return NULL;
  598.     }
  599.     if (!PyFile_Check(f)) {
  600.         PyObject *reader;
  601.         PyObject *args;
  602.         PyObject *result;
  603.         reader = PyObject_GetAttrString(f, "readline");
  604.         if (reader == NULL)
  605.             return NULL;
  606.         if (n <= 0)
  607.             args = Py_BuildValue("()");
  608.         else
  609.             args = Py_BuildValue("(i)", n);
  610.         if (args == NULL) {
  611.             Py_DECREF(reader);
  612.             return NULL;
  613.         }
  614.         result = PyEval_CallObject(reader, args);
  615.         Py_DECREF(reader);
  616.         Py_DECREF(args);
  617.         if (result != NULL && !PyString_Check(result)) {
  618.             Py_DECREF(result);
  619.             result = NULL;
  620.             PyErr_SetString(PyExc_TypeError,
  621.                    "object.readline() returned non-string");
  622.         }
  623.         if (n < 0 && result != NULL) {
  624.             char *s = PyString_AsString(result);
  625.             int len = PyString_Size(result);
  626.             if (len == 0) {
  627.                 Py_DECREF(result);
  628.                 result = NULL;
  629.                 PyErr_SetString(PyExc_EOFError,
  630.                        "EOF when reading a line");
  631.             }
  632.             else if (s[len-1] == '\n') {
  633.                 if (result->ob_refcnt == 1)
  634.                     _PyString_Resize(&result, len-1);
  635.                 else {
  636.                     PyObject *v;
  637.                     v = PyString_FromStringAndSize(s,
  638.                                        len-1);
  639.                     Py_DECREF(result);
  640.                     result = v;
  641.                 }
  642.             }
  643.         }
  644.         return result;
  645.     }
  646.     if (((PyFileObject*)f)->f_fp == NULL)
  647.         return err_closed();
  648.     return getline((PyFileObject *)f, n);
  649. }
  650.  
  651. /* Python method */
  652.  
  653. static PyObject *
  654. file_readline(f, args)
  655.     PyFileObject *f;
  656.     PyObject *args;
  657. {
  658.     int n = -1;
  659.  
  660.     if (f->f_fp == NULL)
  661.         return err_closed();
  662.     if (!PyArg_ParseTuple(args, "|i", &n))
  663.         return NULL;
  664.     if (n == 0)
  665.         return PyString_FromString("");
  666.     if (n < 0)
  667.         n = 0;
  668.     return getline(f, n);
  669. }
  670.  
  671. static PyObject *
  672. file_readlines(f, args)
  673.     PyFileObject *f;
  674.     PyObject *args;
  675. {
  676.     long sizehint = 0;
  677.     PyObject *list;
  678.     PyObject *line;
  679.     char small_buffer[SMALLCHUNK];
  680.     char *buffer = small_buffer;
  681.     size_t buffersize = SMALLCHUNK;
  682.     PyObject *big_buffer = NULL;
  683.     size_t nfilled = 0;
  684.     size_t nread;
  685.     size_t totalread = 0;
  686.     char *p, *q, *end;
  687.     int err;
  688.  
  689.     if (f->f_fp == NULL)
  690.         return err_closed();
  691.     if (!PyArg_ParseTuple(args, "|l", &sizehint))
  692.         return NULL;
  693.     if ((list = PyList_New(0)) == NULL)
  694.         return NULL;
  695.     for (;;) {
  696.         Py_BEGIN_ALLOW_THREADS
  697.         errno = 0;
  698.         nread = fread(buffer+nfilled, 1, buffersize-nfilled, f->f_fp);
  699.         Py_END_ALLOW_THREADS
  700.         if (nread == 0) {
  701.             sizehint = 0;
  702.             if (!ferror(f->f_fp))
  703.                 break;
  704.             PyErr_SetFromErrno(PyExc_IOError);
  705.             clearerr(f->f_fp);
  706.           error:
  707.             Py_DECREF(list);
  708.             list = NULL;
  709.             goto cleanup;
  710.         }
  711.         totalread += nread;
  712.         p = memchr(buffer+nfilled, '\n', nread);
  713.         if (p == NULL) {
  714.             /* Need a larger buffer to fit this line */
  715.             nfilled += nread;
  716.             buffersize *= 2;
  717.             if (big_buffer == NULL) {
  718.                 /* Create the big buffer */
  719.                 big_buffer = PyString_FromStringAndSize(
  720.                     NULL, buffersize);
  721.                 if (big_buffer == NULL)
  722.                     goto error;
  723.                 buffer = PyString_AS_STRING(big_buffer);
  724.                 memcpy(buffer, small_buffer, nfilled);
  725.             }
  726.             else {
  727.                 /* Grow the big buffer */
  728.                 _PyString_Resize(&big_buffer, buffersize);
  729.                 buffer = PyString_AS_STRING(big_buffer);
  730.             }
  731.             continue;
  732.         }
  733.         end = buffer+nfilled+nread;
  734.         q = buffer;
  735.         do {
  736.             /* Process complete lines */
  737.             p++;
  738.             line = PyString_FromStringAndSize(q, p-q);
  739.             if (line == NULL)
  740.                 goto error;
  741.             err = PyList_Append(list, line);
  742.             Py_DECREF(line);
  743.             if (err != 0)
  744.                 goto error;
  745.             q = p;
  746.             p = memchr(q, '\n', end-q);
  747.         } while (p != NULL);
  748.         /* Move the remaining incomplete line to the start */
  749.         nfilled = end-q;
  750.         memmove(buffer, q, nfilled);
  751.         if (sizehint > 0)
  752.             if (totalread >= (size_t)sizehint)
  753.                 break;
  754.     }
  755.     if (nfilled != 0) {
  756.         /* Partial last line */
  757.         line = PyString_FromStringAndSize(buffer, nfilled);
  758.         if (line == NULL)
  759.             goto error;
  760.         if (sizehint > 0) {
  761.             /* Need to complete the last line */
  762.             PyObject *rest = getline(f, 0);
  763.             if (rest == NULL) {
  764.                 Py_DECREF(line);
  765.                 goto error;
  766.             }
  767.             PyString_Concat(&line, rest);
  768.             Py_DECREF(rest);
  769.             if (line == NULL)
  770.                 goto error;
  771.         }
  772.         err = PyList_Append(list, line);
  773.         Py_DECREF(line);
  774.         if (err != 0)
  775.             goto error;
  776.     }
  777.   cleanup:
  778.     if (big_buffer) {
  779.         Py_DECREF(big_buffer);
  780.     }
  781.     return list;
  782. }
  783.  
  784. static PyObject *
  785. file_write(f, args)
  786.     PyFileObject *f;
  787.     PyObject *args;
  788. {
  789.     char *s;
  790.     int n, n2;
  791.     if (f->f_fp == NULL)
  792.         return err_closed();
  793.     if (!PyArg_Parse(args, "s#", &s, &n))
  794.         return NULL;
  795.     f->f_softspace = 0;
  796.     Py_BEGIN_ALLOW_THREADS
  797.     errno = 0;
  798.     n2 = fwrite(s, 1, n, f->f_fp);
  799.     Py_END_ALLOW_THREADS
  800.     if (n2 != n) {
  801.         PyErr_SetFromErrno(PyExc_IOError);
  802.         clearerr(f->f_fp);
  803.         return NULL;
  804.     }
  805.     Py_INCREF(Py_None);
  806.     return Py_None;
  807. }
  808.  
  809. static PyObject *
  810. file_writelines(f, args)
  811.     PyFileObject *f;
  812.     PyObject *args;
  813. {
  814.     int i, n;
  815.     if (f->f_fp == NULL)
  816.         return err_closed();
  817.     if (args == NULL || !PyList_Check(args)) {
  818.         PyErr_SetString(PyExc_TypeError,
  819.                "writelines() requires list of strings");
  820.         return NULL;
  821.     }
  822.     n = PyList_Size(args);
  823.     f->f_softspace = 0;
  824.     Py_BEGIN_ALLOW_THREADS
  825.     errno = 0;
  826.     for (i = 0; i < n; i++) {
  827.         PyObject *line = PyList_GetItem(args, i);
  828.         int len;
  829.         int nwritten;
  830.         if (!PyString_Check(line)) {
  831.             Py_BLOCK_THREADS
  832.             PyErr_SetString(PyExc_TypeError,
  833.                    "writelines() requires list of strings");
  834.             return NULL;
  835.         }
  836.         len = PyString_Size(line);
  837.         nwritten = fwrite(PyString_AsString(line), 1, len, f->f_fp);
  838.         if (nwritten != len) {
  839.             Py_BLOCK_THREADS
  840.             PyErr_SetFromErrno(PyExc_IOError);
  841.             clearerr(f->f_fp);
  842.             return NULL;
  843.         }
  844.     }
  845.     Py_END_ALLOW_THREADS
  846.     Py_INCREF(Py_None);
  847.     return Py_None;
  848. }
  849.  
  850. static PyMethodDef file_methods[] = {
  851.     {"readline",    (PyCFunction)file_readline, 1},
  852.     {"read",    (PyCFunction)file_read, 1},
  853.     {"write",    (PyCFunction)file_write, 0},
  854.     {"fileno",    (PyCFunction)file_fileno, 0},
  855.     {"seek",    (PyCFunction)file_seek, 0},
  856. #ifdef HAVE_FTRUNCATE
  857.     {"truncate",    (PyCFunction)file_truncate, 0},
  858. #endif
  859.     {"tell",    (PyCFunction)file_tell, 0},
  860.     {"readinto",    (PyCFunction)file_readinto, 0},
  861.     {"readlines",    (PyCFunction)file_readlines, 1},
  862.     {"writelines",    (PyCFunction)file_writelines, 0},
  863.     {"flush",    (PyCFunction)file_flush, 0},
  864.     {"close",    (PyCFunction)file_close, 0},
  865.     {"isatty",    (PyCFunction)file_isatty, 0},
  866.     {NULL,        NULL}        /* sentinel */
  867. };
  868.  
  869. #define OFF(x) offsetof(PyFileObject, x)
  870.  
  871. static struct memberlist file_memberlist[] = {
  872.     {"softspace",    T_INT,        OFF(f_softspace)},
  873.     {"mode",    T_OBJECT,    OFF(f_mode),    RO},
  874.     {"name",    T_OBJECT,    OFF(f_name),    RO},
  875.     /* getattr(f, "closed") is implemented without this table */
  876.     {"closed",    T_INT,        0,        RO},
  877.     {NULL}    /* Sentinel */
  878. };
  879.  
  880. static PyObject *
  881. file_getattr(f, name)
  882.     PyFileObject *f;
  883.     char *name;
  884. {
  885.     PyObject *res;
  886.  
  887.     res = Py_FindMethod(file_methods, (PyObject *)f, name);
  888.     if (res != NULL)
  889.         return res;
  890.     PyErr_Clear();
  891.     if (strcmp(name, "closed") == 0)
  892.         return PyInt_FromLong((long)(f->f_fp == 0));
  893.     return PyMember_Get((char *)f, file_memberlist, name);
  894. }
  895.  
  896. static int
  897. file_setattr(f, name, v)
  898.     PyFileObject *f;
  899.     char *name;
  900.     PyObject *v;
  901. {
  902.     if (v == NULL) {
  903.         PyErr_SetString(PyExc_AttributeError,
  904.                 "can't delete file attributes");
  905.         return -1;
  906.     }
  907.     return PyMember_Set((char *)f, file_memberlist, name, v);
  908. }
  909.  
  910. PyTypeObject PyFile_Type = {
  911.     PyObject_HEAD_INIT(&PyType_Type)
  912.     0,
  913.     "file",
  914.     sizeof(PyFileObject),
  915.     0,
  916.     (destructor)file_dealloc, /*tp_dealloc*/
  917.     0,        /*tp_print*/
  918.     (getattrfunc)file_getattr, /*tp_getattr*/
  919.     (setattrfunc)file_setattr, /*tp_setattr*/
  920.     0,        /*tp_compare*/
  921.     (reprfunc)file_repr, /*tp_repr*/
  922. };
  923.  
  924. /* Interface for the 'soft space' between print items. */
  925.  
  926. int
  927. PyFile_SoftSpace(f, newflag)
  928.     PyObject *f;
  929.     int newflag;
  930. {
  931.     int oldflag = 0;
  932.     if (f == NULL) {
  933.         /* Do nothing */
  934.     }
  935.     else if (PyFile_Check(f)) {
  936.         oldflag = ((PyFileObject *)f)->f_softspace;
  937.         ((PyFileObject *)f)->f_softspace = newflag;
  938.     }
  939.     else {
  940.         PyObject *v;
  941.         v = PyObject_GetAttrString(f, "softspace");
  942.         if (v == NULL)
  943.             PyErr_Clear();
  944.         else {
  945.             if (PyInt_Check(v))
  946.                 oldflag = PyInt_AsLong(v);
  947.             Py_DECREF(v);
  948.         }
  949.         v = PyInt_FromLong((long)newflag);
  950.         if (v == NULL)
  951.             PyErr_Clear();
  952.         else {
  953.             if (PyObject_SetAttrString(f, "softspace", v) != 0)
  954.                 PyErr_Clear();
  955.             Py_DECREF(v);
  956.         }
  957.     }
  958.     return oldflag;
  959. }
  960.  
  961. /* Interfaces to write objects/strings to file-like objects */
  962.  
  963. int
  964. PyFile_WriteObject(v, f, flags)
  965.     PyObject *v;
  966.     PyObject *f;
  967.     int flags;
  968. {
  969.     PyObject *writer, *value, *args, *result;
  970.     if (f == NULL) {
  971.         PyErr_SetString(PyExc_TypeError, "writeobject with NULL file");
  972.         return -1;
  973.     }
  974.     else if (PyFile_Check(f)) {
  975.         FILE *fp = PyFile_AsFile(f);
  976.         if (fp == NULL) {
  977.             err_closed();
  978.             return -1;
  979.         }
  980.         return PyObject_Print(v, fp, flags);
  981.     }
  982.     writer = PyObject_GetAttrString(f, "write");
  983.     if (writer == NULL)
  984.         return -1;
  985.     if (flags & Py_PRINT_RAW)
  986.         value = PyObject_Str(v);
  987.     else
  988.         value = PyObject_Repr(v);
  989.     if (value == NULL) {
  990.         Py_DECREF(writer);
  991.         return -1;
  992.     }
  993.     args = Py_BuildValue("(O)", value);
  994.     if (args == NULL) {
  995.         Py_DECREF(value);
  996.         Py_DECREF(writer);
  997.         return -1;
  998.     }
  999.     result = PyEval_CallObject(writer, args);
  1000.     Py_DECREF(args);
  1001.     Py_DECREF(value);
  1002.     Py_DECREF(writer);
  1003.     if (result == NULL)
  1004.         return -1;
  1005.     Py_DECREF(result);
  1006.     return 0;
  1007. }
  1008.  
  1009. int
  1010. PyFile_WriteString(s, f)
  1011.     char *s;
  1012.     PyObject *f;
  1013. {
  1014.     if (f == NULL) {
  1015.         /* Should be caused by a pre-existing error */
  1016.         if(!PyErr_Occurred())
  1017.             PyErr_SetString(PyExc_SystemError,
  1018.                     "null file for PyFile_WriteString");
  1019.         return -1;
  1020.     }
  1021.     else if (PyFile_Check(f)) {
  1022.         FILE *fp = PyFile_AsFile(f);
  1023.         if (fp == NULL) {
  1024.             err_closed();
  1025.             return -1;
  1026.         }
  1027.         fputs(s, fp);
  1028.         return 0;
  1029.     }
  1030.     else if (!PyErr_Occurred()) {
  1031.         PyObject *v = PyString_FromString(s);
  1032.         int err;
  1033.         if (v == NULL)
  1034.             return -1;
  1035.         err = PyFile_WriteObject(v, f, Py_PRINT_RAW);
  1036.         Py_DECREF(v);
  1037.         return err;
  1038.     }
  1039.     else
  1040.         return -1;
  1041. }
  1042.